package com.jo.proxy;

import com.jo.advisor.AdvisedSupport;
import com.jo.advisor.TargetSource;
import com.jo.interceptor.MethodInterceptor;
import com.jo.invocation.MethodInvocation;
import com.jo.invocation.ReflectionMethodInvocation;
import com.jo.util.AopUtil;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

/**
 * jdk方式生成代理类
 * @author Jo
 * @date 2018/1/25
 */
public class JdkAopProxy implements AopProxy, InvocationHandler {
    private AdvisedSupport advisedSupport;

    public JdkAopProxy(AdvisedSupport advisedSupport) {
        this.advisedSupport = advisedSupport;
    }

    @Override
    public Object getProxy() {
        return getProxy(this.getClass().getClassLoader());
    }

    @Override
    public Object getProxy(ClassLoader classLoader) {
        Class<?>[] interfaces = this.advisedSupport.getTargetSource().getTargetClass().getInterfaces();
        return Proxy.newProxyInstance(classLoader, interfaces, this);
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        TargetSource targetSource = this.advisedSupport.getTargetSource();
        List<MethodInterceptor> methodInterceptors = AopUtil.getMethodInterceptors(this.advisedSupport);

        MethodInvocation invocation = new ReflectionMethodInvocation(proxy, targetSource.getTarget(),
                method, args, methodInterceptors);
        return invocation.proceed();
    }
}
